`include "definitions.sv"
`include "NewLabel_components.sv"

module NewLabel_top
(
	input logic arstn,
	input logic cclk,
	input logic sclk,
	input logic mclk,

	inout logic [23:0]	data_s,
	input logic [4:0]	addr_s,
	input logic			cs_s,
	input logic 		wr_s,
	output logic		wr_full_s,
	output logic		rd_empty_s,

	// auxmem if
	inout logic [23:0]	data_m,
	output logic [25:0]	addr_m,
	output logic		cs_m,
	output logic [2:0]	gpctrl_m,

	// Others
	output logic err_s,
	output logic finish_s
);

////////////////////////////////////////////////////////
//
//	reset sync
//
logic c_rstn;
logic c_rstn_p;
always_ff @(posedge cclk or negedge arstn)
begin
	if(!arstn)
		{c_rstn, c_rstn_p} <= 2'b0;
	else
		{c_rstn, c_rstn_p} <= {c_rstn_p, 1'b1};
end

logic s_rstn;
logic s_rstn_p;
always_ff @(posedge sclk or negedge arstn)
begin
	if(!arstn)
		{s_rstn, s_rstn_p} <= 2'b0;
	else
		{s_rstn, s_rstn_p} <= {s_rstn_p, 1'b1};
end

logic m_rstn;
logic m_rstn_p;
always_ff @(posedge mclk or negedge arstn)
begin
	if(!arstn)
		{m_rstn, m_rstn_p} <= 2'b0;
	else
		{m_rstn, m_rstn_p} <= {m_rstn_p, 1'b1};
end


logic [23:0]	data_in_s;
logic [23:0]	data_out_s;
logic [23:0]	data_out_fifo;
logic [23:0]	data_out_rf;

NewLabel_sysif sysif_inst
(
	.s_rstn(s_rstn),
	.sclk(sclk),
	.oe(oe),
	.addr(addr_s),
	.cs(cs_s),
	.wr(wr_s),
	.wr_valid(wr_valid_s),
	.wr_full(wr_full_s),
	.rd_valid(rd_valid_s),
	.rd_empty(rd_empty_s),
	.cs_rf(cs_rf),
	.wr_rf(wr_rf),
	.err_sysif()
);

logic [23:0]	data_m_in;
logic [23:0]	data_m_out;
logic [47:0]	data_out_m;
logic [47:0]	data_in_m;

NewLabel_memif memif_inst
(
	.m_rstn(m_rstn),
	.mclk(mclk),

	//outer
	//.mclk_o(mclk_o),
	.data_i(data_m_in),
	.data_o(data_m_out),
	.addr_o(addr_m),
	.cs_o(cs_m),
	.gpctrl_o(gpctrl_m),
	.oe_m(oe_m),

	//inner
	.data_i_m(data_out_m),
	.data_o_m(data_in_m),
	
	.wr_valid(wr_valid_m),
	.wr_full(wr_full_m),
	.rd_valid(rd_valid_m),
	.rd_empty(rd_empty_m),
	
	.err_memif(),
	.finish_int(finish_s)
);

NewLabel_shell shell_inst
(
	.c_rstn(c_rstn),
	.s_rstn(s_rstn),
	.m_rstn(m_rstn),
	.cclk(cclk),

	.sclk(sclk),
	.data_in_s(data_in_s[7:0]),
	.wr_valid_s(wr_valid_s),
	.wr_full_s(wr_full_s),
	.wr_empty_s(wr_empty_s),
	.fifo_util_s(),

	.data_out_s(data_out_fifo),
	.rd_valid_s(rd_valid_s),
	.rd_empty_s(rd_empty_s),
	.rd_full_s(rd_full_s),

	// fifo_out
	.data_out_m(data_out_m),
	.rd_valid_m(rd_valid_m),
	.rd_empty_m(rd_empty_m),
	.rd_full_m(),

	// fifo_in
	.mclk(mclk),
	.data_in_m(data_in_m),
	.wr_valid_m(wr_valid_m),
	.wr_full_m(wr_full_m),
	.wr_empty_m(),
	.fifo_util_m(),

	.data_rf_is(data_in_s),
	.data_rf_os(data_out_rf),
	.addr_rf_is(addr_s),
	.cs_rf_is(cs_rf),
	.wr_rf_is(wr_rf),
	.ack_rf_os(),
	
	.err_int_s(),
	.finish_int_s(finish_s)
);


assign data_out_s = cs_rf? data_out_rf : data_out_fifo;
assign data_in_s = oe? 8'h0 : data_s;
assign data_s = oe? data_out_s : 24'hz;

assign data_m_in = oe_m? 8'h0 : data_m;
assign data_m = oe_m? data_m_out : 24'hz;

endmodule
